<template>
	<div class="table-container layout-padding">
		<div class="table-padding layout-padding-view layout-padding-auto">
			<HTableControl
				:config="state.tableState.config"
				:header="state.tableState.header"
				:selectedRows="state.tableState.selectedRows"
				:tableSearch="state.tableSearch"
				@sort="sortHeader => (state.tableState.header = sortHeader)"
				@search="onTableSearch"
				@refresh="
					() => {
						initDictData();
						initTableData();
					}
				"
			>
				<template v-slot:operationBtn>
					<el-button type="success" @click="onTableUpdate('add')">添加核酸采样点</el-button>
					<el-button type="danger" :disabled="state.tableState.selectedRows.length === 0">批量删除</el-button>
				</template>
			</HTableControl>
			<HTable
				class="h-table"
				v-model:selectedRows="state.tableState.selectedRows"
				:config="state.tableState.config"
				:header="state.tableState.header"
				:data="state.tableState.data"
				:pageNum="state.params.page"
				:pageSize="state.params.limit"
				@pageChange="onTablePageChange"
			>
				<template v-slot:expandRow="{ scope }">
					<div class="pl15">
						<el-button type="primary" @click="onClickToLog(scope)">Row expand</el-button>
					</div>
				</template>
				<template v-slot:time="{ scope }">
					{{
						dayjs(scope.row["time"][0]).format("HH:mm") + " ~ " + dayjs(scope.row["time"][1]).format("HH:mm")
					}}
				</template>
				<template v-slot:operation="{ scope }">
					<el-button link type="primary" @click="onTableUpdate('edit', scope.row)">修改</el-button>
					<el-button link type="danger" @click="onTableDelete(scope.row)">删除</el-button>
				</template>
			</HTable>
		</div>
		<HTableDialog
			ref="tableDialogRef"
			title="核酸采样点"
			:options="state.tableDialogOptions"
			@submit="updateTableData"
		/>
	</div>
</template>

<script setup lang="ts" name="tableDemo">
import { defineAsyncComponent, reactive, ref, onMounted } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { getMechanismData, getCascaderData, getTableData } from "/@/api/demo";
import { deleteEmptyProperty } from "/@/utils/commonFunction";
import dayjs from "dayjs";

// 引入组件
const HTable = defineAsyncComponent(() => import("/@/components/table/index.vue"));
const HTableControl = defineAsyncComponent(() => import("/@/components/table/tableControl.vue"));
const HTableDialog = defineAsyncComponent(() => import("/@/components/table/tableDialog.vue"));

// 定义变量内容
const tableDialogRef = ref<RefType>();
const state = reactive({
	// 表格配置
	tableState: <TableStateType>{
		// 配置项
		config: {
			total: 0,
			loading: false, // loading 状态
			isBorder: true, // 是否显示表格边框
			isSerialNo: true, // 是否显示表格序号
			isSelection: true, // 是否显示表格多选
			isOperate: true, // 是否显示表格操作栏
			opWidth: 150, // 表格操作栏的宽度
			isPagination: true, // 是否显示表格分页
		},
		// 表头内容
		header: [
			{ key: "name", title: "应检尽检核酸采样点名称", type: "text", isCheck: true },
			{ key: "address", title: "详细地址", type: "text", isCheck: true },
			{ key: "phone", title: "采样点联系电话", type: "text", isCheck: true },
			{
				key: "mechanism",
				title: "核酸机构",
				type: "mapOpt",
				mapOpt: {},
				isCheck: true,
			},
			{ key: "time", title: "开放时间", type: "customCell", slotName: "time", isCheck: true },
			{
				key: "isSupport",
				title: "是否支持24小时核酸检测",
				type: "mapOpt",
				mapOpt: {
					0: "否",
					1: "是",
				},
				isCheck: true,
			},
			{
				key: "image",
				title: "图片描述",
				type: "image",
				colWidth: "126",
				align: "center",
				resizable: false,
				picWidth: "100",
				picHeight: "100",
				isCheck: true,
			},
		],
		// 表格数据
		data: [],
		// 表格选中行
		selectedRows: [],
	},
	// 条件搜索配置
	tableSearch: <TableSearchType[]>[
		{
			label: "采样点名称",
			prop: "name",
			placeholder: "请输入应检尽检核酸采样点名称",
			required: true,
			type: "input",
		},
		{ label: "详细地址", prop: "address", placeholder: "请输入详细地址", required: false, type: "input" },
		{
			label: "联系电话",
			prop: "phone",
			placeholder: "请输入采样点联系电话",
			required: false,
			type: "input",
		},
		{
			label: "核酸机构",
			prop: "mechanism",
			placeholder: "请选择核酸机构",
			required: false,
			type: "select",
			options: [],
		},
		{ label: "开放时间", prop: "time", placeholder: "请选择", required: false, type: "timeRange" },
		{
			label: "支持24小时",
			prop: "isSupport",
			placeholder: "请选择",
			required: false,
			type: "select",
			options: [
				{ label: "是", value: 1 },
				{ label: "否", value: 0 },
			],
		},
		{ label: "图片描述", prop: "image", placeholder: "请输入图片描述", required: false, type: "input" },
	],
	// 通用弹窗配置
	tableDialogOptions: <TableDialogOptionsType[]>[
		{
			label: "采样点名称",
			prop: "name",
			placeholder: "请输入应检尽检核酸采样点名称",
			required: true,
			defaultValue: "",
			type: "input",
		},
		{
			label: "详细地址",
			prop: "address",
			placeholder: "请输入详细地址",
			required: true,
			defaultValue: "",
			type: "input",
		},
		{
			label: "联系电话",
			prop: "phone",
			placeholder: "请输入采样点联系电话",
			required: true,
			defaultValue: "",
			type: "input",
		},
		{
			label: "开放时间",
			prop: "time",
			placeholder: "请选择开放时间",
			required: true,
			defaultValue: [],
			type: "timeRange",
		},
		{
			label: "支持24小时",
			prop: "isSupport",
			placeholder: "请选择",
			required: true,
			defaultValue: 1,
			type: "switch",
			options: [
				{ label: "是", value: 1 },
				{ label: "否", value: 0 },
			],
		},
		{
			label: "级联数据模拟",
			prop: "cascaderMock",
			placeholder: "请选择级联数据",
			required: true,
			defaultValue: [],
			type: "cascader",
			cascaderOptions: [],
			cascaderProps: {
				expandTrigger: "hover",
				value: "deptName",
				label: "deptName",
				children: "children",
			},
		},
		{
			label: "核酸机构",
			prop: "mechanism",
			placeholder: "请选择核酸机构",
			required: true,
			defaultValue: "",
			size: "large",
			type: "select",
			options: [],
		},
	],
	// 搜索参数
	params: {
		page: 1,
		limit: 10,
	},
});

// 初始化字典数据
const initDictData = async () => {
	try {
		// 核酸机构
		const { code: code1, data: data1 } = await getMechanismData();
		if (code1 !== 200) return ElMessage.error("核酸机构数据获取失败");
		const mechanismMapOpt = {};
		data1.data.forEach((item: EmptyObjectType) => {
			mechanismMapOpt[item.value] = item.label;
		});
		state.tableState.header.find(item => item.key === "mechanism")!.mapOpt = mechanismMapOpt;
		state.tableSearch.find(item => item.prop === "mechanism")!.options = data1.data;
		state.tableDialogOptions.find(item => item.prop === "mechanism")!.options = data1.data;

		// 级联模拟数据
		const { code: code2, data: data2 } = await getCascaderData();
		if (code2 !== 200) return ElMessage.error("级联模拟数据获取失败");
		state.tableDialogOptions.find(item => item.prop === "cascaderMock")!.cascaderOptions = data2.data;
	} catch (error) {
		console.error(error);
		ElMessage.error("字典数据请求失败");
	}
};
// 初始化表格数据
const initTableData = async () => {
	try {
		state.tableState.config.loading = true;
		const { code, data } = await getTableData(state.params);
		if (code !== 200) return ElMessage.error("表格数据获取失败");
		state.tableState.data = data.data.map((item: EmptyObjectType) => {
			item.time = item.time.map((timeItem: string) => dayjs(timeItem, "HH:mm"));
			return item;
		});
		state.tableState.config.total = data.total;
		state.tableState.config.loading = false;
	} catch (error) {
		console.error(error);
		ElMessage.error("表格数据请求失败");
		state.tableState.config.loading = false;
	}
};
// 更新表格数据
const updateTableData = async (type: string, data: EmptyObjectType) => {
	try {
		await initTableData();
	} catch (error) {
		console.error(error);
		ElMessage.error("表格数据提交失败");
	}
};

// 新增&修改
const onTableUpdate = (type: string, row?: EmptyObjectType) => {
	tableDialogRef.value.openDialog(type, row);
};
// 删除
const onTableDelete = (row: EmptyObjectType) => {
	ElMessageBox.confirm(`此操作将删除【${row.name}】, 是否继续?`, "提示", {
		confirmButtonText: "删除",
		cancelButtonText: "取消",
		type: "warning",
	}).then(async () => {
		try {
			ElMessage.success(`删除【${row.name}】成功`);
			await initTableData();
		} catch (error) {
			console.error(error);
			ElMessage.error(`数据提交失败`);
		}
	});
};
// 输出slot作用域的数据
const onClickToLog = (scope: EmptyObjectType) => {
	console.log(scope);
};

// 条件搜索
const onTableSearch = (data: EmptyObjectType, isReset: Boolean = false) => {
	state.params = deleteEmptyProperty({ ...state.params, ...data }); // 更新搜索参数
	state.params.page = 1; // 触发查询时重置页数为1
	initTableData();
};
// 分页改变
const onTablePageChange = (page: TablePageType) => {
	state.params.page = page.page;
	state.params.limit = page.limit;
	initTableData();
};

// 页面挂载后
onMounted(() => {
	initDictData();
	initTableData();
});
</script>

<style scoped lang="scss">
.table-container {
	.table-padding {
		padding: 10px;
		.h-table {
			flex: 1;
			overflow: hidden;
		}
	}
}
</style>
